package com.kele.shiro.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kele.shiro.entity.*;
import com.kele.shiro.mapper.*;
import com.kele.shiro.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kele.shiro.utils.Saultutils;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author kele
 * @since 2022-10-24
 */
@Service
public class UserServiceImpl extends ServiceImpl< UserMapper, User > implements UserService {
	@Autowired
	UserMapper userMapper;

	@Autowired
	TRoleMapper tRoleMapper;

	@Autowired
	TPersMapper tPersMapper;

	@Autowired
	TRolePermsMapper tRolePermsMapper;

	@Autowired
	TUserRoleMapper tUserRoleMapper;
	@Override
	public void register(User user) {
		//处理业务调用dao
		//1.生成随机盐
		String salt = Saultutils.getSault();
		//2.将随机盐保存到数据
		user.setSalt(salt);
		//3.明文密码进行md5 + salt + hash散列
		Md5Hash md5Hash = new Md5Hash(user.getPassword(),salt,1024);
		user.setPassword(md5Hash.toHex());
		boolean save=save( user );
		if (save) {
			System.out.println("successful" );
		}else {
			System.out.println("fail" );
		}


	}

	@Override
	public User findByUserName(String username) {
		return this.getOne(new LambdaQueryWrapper<User>().eq(User::getUsername, username));
	}

	/**
	 * 查询所有的角色
	 * @param user
	 * @return
	 */
	@Override
	public List<String> findRoles(User user) {

		final User user1 = userMapper.findRolesByUserName(user.getUsername());
		final List< Role > roles = user1.getRoles();
		final List<String> collect = roles.stream().map(role -> {
			return role.getName();
		}).collect( Collectors.toList());

		return collect;
	}

	/**
	 * 查询所有的权限
	 * @param user
	 * @return
	 */
	@Override
	public List<String> findPermissions(User user) {


		//这里的一切有所修改了
		 User user1 = userMapper.findRolesByUserName( user.getUsername() );
		List< Role > roles=user1.getRoles( );
		final ArrayList<String> result = new ArrayList<>();

		roles.forEach(role -> {
			final List< Perms> perms = userMapper.findPermsByRoleId(role.getId() + "");
			perms.forEach(pers -> {
				result.add(pers.getName());
			});
		});

		return result;
	}


	//使用mp来实现多表查询所有的权限的名称
	@Override
	public List<String> findPermissionsByCodes(User user) {

		//根据userid来查询中间表中的所有role.id
		List< TUserRole > userid=tUserRoleMapper.selectList( new QueryWrapper< TUserRole >( ).eq( "userid",user.getId( ) ) );


		//将查询到的所有中间表对象换为角色id的集合
		List< Integer > rolesIds=userid.stream( ).map( s->s.getRoleid( ) ).collect( Collectors.toList( ) );


		//直接查询角色表中所有的角色，减少数据库的交互
		List< Role > roles=tRoleMapper.selectList( null );


		//创建一个list集合用来保存已经查询到的所有角色id集合
		ArrayList< Integer > roleids2=new ArrayList<>( );

		roles.forEach( s->roleids2.add(Integer.parseInt( s.getId() )) );

		//创建一个保存所有角色名称的集合
		ArrayList< Integer > roleNames=new ArrayList<>( );

		//遍历查询到的角色id
		for(Integer rolesId: rolesIds) {
			if(roleids2.contains( rolesId )){
				roleNames.add( rolesId );
			}
		}

		//创建一个map集合用来保存已经查询到的所有权限集合
		HashMap< Integer, String > permsMap=new HashMap<>( );
		//查询所有的权限对象
		List< TRolePerms > tRolePerms=tRolePermsMapper.selectList( null);

		//创建一个集合收集所有权限的id
		Set<Integer> permsSet=new HashSet<>(  );
		//收集所有的权限的id
		for(Integer roleName: roleNames) {
			for(TRolePerms tRolePerm: tRolePerms) {
				if(tRolePerm.getRoleid()==roleName){
					permsSet.add( tRolePerm.getPermsid() );
				}
			}
		}


		//设置一个保存所有权限名的集合
		List<String> pName=new ArrayList<>(  );

		//设置保存所有权限的map集合
		HashMap<Integer,String> hashMap=new HashMap<>(  );
		//查询所有权限的集合
		List<Perms> perms=tPersMapper.selectList(null);

		perms.forEach( s->hashMap.put(Integer.parseInt( s.getId() ),s.getName() ) );


		for(Integer integer: permsSet) {
			if(hashMap.containsKey( integer )){
				pName.add( hashMap.get( integer ) );
			}
		}


		return pName;
	}

	//使用mp来实现多表查询所有的角色的名称
	@Override
	public List<String> findRolesByCodes(User user) {

		//根据userid来查询中间表中的所有role.id
		List< TUserRole > userid=tUserRoleMapper.selectList( new QueryWrapper< TUserRole >( ).eq( "userid",user.getId( ) ) );


		//将查询到的所有中间表对象换为角色id的集合
		List< Integer > rolesIds=userid.stream( ).map( s->s.getRoleid( ) ).collect( Collectors.toList( ) );


		//根据去角色表中查询所有的角色对象
		//直接查询角色表中所有的角色，减少数据库的交互
		List< Role > roles=tRoleMapper.selectList( null );


		//创建一个map集合用来保存已经查询到的所有角色集合
		HashMap< Integer, String > rolesMap=new HashMap<>( );

		roles.forEach( s->rolesMap.put(Integer.parseInt( s.getId() ),s.getName()) );

		//创建一个保存所有角色名称的集合
		ArrayList< String > roleNames=new ArrayList<>( );

		//遍历查询到的角色id
		for(Integer rolesId: rolesIds) {
			if(rolesMap.containsKey( rolesId )){
				roleNames.add( rolesMap.get( rolesId ) );
			}
		}

		return roleNames;
	}

}
